package com.iwhalecloud.citybrain.flow.platform.manager.domain.repository;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.iwhalecloud.citybrain.flow.platform.manager.common.ResponseResult;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowFormAppInfoVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.FlowFormExternalInfoDomain;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.form.*;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.monitor.FlowTaskTraceVo;

import java.util.List;
import java.util.Map;

/**
 * @author cheng.huaxing
 * @date 2019-02-27
 */
public interface FlowFormRepository {
    /**
     * 表单部署
     *
     * @param formKey
     * @param parentDeploymentId
     */
    void deploy(String formKey, String parentDeploymentId);

    /**
     * 创建表单
     *
     * @param formCreateVO
     * @return
     */
    String create(FormCreateVO formCreateVO);

    /**
     * 复制表单
     * 复制表单
     *
     * @param formCopyVO 参数
     * @return 结果
     */
    String copy(FormCopyVO formCopyVO);

    /**
     * 表单详情
     *
     * @param formId 表单id
     * @return
     */
    FormCreateVO detail(String formId);

    /**
     * 根据form编号获取form字段明细
     * @param formId
     * @return
     */
    List<FormFieldDTO> getFormFieldDetail(String formId);


    ExternalFormDetailDTO externalDetail(String formId);

    /**
     * 保存表单
     *
     * @param formCreateVO
     * @return
     */
    Boolean save(FormCreateVO formCreateVO);

    /**
     * 删除表单
     *
     * @param formId
     * @return 返回null表单不存在
     */
    Boolean delete(String formId);

    /**
     * 更新表单状态
     *
     * @param formId 表单id
     * @param status 状态
     * @return
     */
    Boolean updateFormStatus(String formId, Integer status);

    /**
     * 判断表单是否已关联
     *
     * @param formId 表单ID
     * @return
     */
    Boolean isFormAssociated(String formId);

    /**
     * 删除部署表单
     *
     * @param formDeployId
     * @return 返回null部署表单不存在
     */
    Boolean deploymentDelete(String formDeployId);

    /**
     * 查询已部署表单
     *
     * @param formDeployId
     * @return
     */
    FormCreateVO findDeploymentById(String formDeployId);

    /**
     * 查询已部署表单
     *
     * @param formKey             表单key
     * @param processDefinitionId 流程定义id
     * @return 已部署的表单信息
     * @deprecated 这个方法本来是用来获取发起流程时，流程关联的表单信息的，由于需求变更，在模型部署阶段，不会固化
     * 表单数据，而是在每次发起流程时，动态查询最新已发布的表单版本，用{@link #findDeployForm(java.lang.String)}
     */
    @Deprecated
    FormCreateVO findFormDeployment(String formKey, String processDefinitionId);

    /**
     * 流程发起时，查询流程关联的表单
     *
     * @param formKey 表单key
     * @return 最新的已发布的表单信息
     */
    FormCreateVO findDeployForm(String formKey);


    /**
     * 根据保单编码查询表单编号
     * @param formKey
     * @return
     */
    String findFormIdByFormKey(String formKey);




    /**
     * 根据流程实例id查询启动表单数据
     *
     * @param processInstanceId 流程实例id
     * @return 启动表单数据
     */
    ProcessInstanceStartFormDetailVo findStartFormDetail(String processInstanceId);


    /**
     * 获取外部表单的开始表单详情
     * @param processInstanceId
     * @return
     */
    ObjectNode filledExternalFormInfo(String processInstanceId,String taskId);

    /**
     * 获取任务节点的历史外置表单详情
     * @param taskId
     * @return
     */
    HistoryExternalTaskFormDTO historyExternalTaskForm(String taskId);
    /**
     * 获取流程的历史外置表单详情
     * @param processInstanceId
     * @return
     */
    HistoryExternalProcessFormDTO historyExternalProcessForm(String processInstanceId);

    /**
     * 根据任务id获取关联的表单信息
     *
     * @param taskId      任务id
     * @param includeData 是否包含填报的数据
     * @return 表单信息
     */
    TaskFormDetailVo findTaskFormDetail(String taskId, boolean includeData);


    /**
     * 获取任务关联的表单
     *
     * @param tasks       任务节点
     * @param includeData 是否包含填报的数据
     * @return 表单schema + 数据
     */
    List<TaskFormDetailVo> findTaskFormDetail(List<FlowTaskTraceVo> tasks, boolean includeData);

    /**
     * 表单列表
     *
     * @param formQueryVO
     * @return
     */
    List<FlowFormAppInfoVo> list(FormQueryVO formQueryVO);

    /**
     * 获取外置表单信息
     * @author 司疆
     */
    FlowExternalFormInfoDTO analyzeExternalFormInfo(FormAnalyzeDTO formAnalyzeDTO);

    /**
     * 判断是否为外置表单,根据key来判断，key可以为formkey,definationid和processid
     * @author 司疆
     * @param externalFormQueryDTO
     * @return
     */
    boolean isExternalForm(ExternalFormQueryDTO externalFormQueryDTO);

    /**
     * 根据流程实例id或者任务id获取全局变量
     * @param processInstanceId
     * @param taskId
     * @return
     */
    Map<String,Object> getFormVariables(String processInstanceId, String taskId);

    /**
     * 根据formkey查找外置表单信息
     * @param formKey
     * @return
     */
    FlowFormExternalInfoDomain findExternalFormInfo(String formKey);

    /**
     * 获取变量经过渲染的外置表单信息
     * @param formKey
     * @param taskId
     * @return
     */
    FlowFormExternalInfoDomain findRenderExternalFormInfo(String formKey, String taskId);

    /**
     * 根据流程定义获取外部表单key值
     * @param processDefinitionKey
     * @return
     */
    String resolveFormKeyFromDefinitionKey(String processDefinitionKey);

    /**
     * 根据任务id获取表单key值
     * @param taskId
     * @return
     */
    String resolveFormKeyFromTaskId(String taskId);

    /**
     * 根据流程实例id获取表单key
     * @param instanceId
     * @return
     */
    String resolveFormKeyFromInstanceId(String instanceId);

    /**
     * 查找流程模型绑定的外置表单描述信息文件
     * @param modelId
     * @return
     */
    List<ExternalFormInfoTransferDTO> findBindExternalFormWithModel(String modelId);

    /**
     * 批量导入外置表单描述信息文件
     * @param externalFormInfoTransferDTOList
     */
    boolean insertExternalFormBatch(List<ExternalFormInfoTransferDTO> externalFormInfoTransferDTOList);

    /**
     * 批量插入数据
     * @param formFieldLimitDomainList
     * @return
     */
    boolean batchInsertFormFieldList(List<FormFieldLimitDomain> formFieldLimitDomainList);

    /**
     * 根据部署编号、表单编号、节点编码查询节点表单字段限制
     * @param deployId
     * @param formId
     * @param nodeCode
     * @return
     */
    List<FormFieldLimitDomain> getFormFieldLimitByNodeCode(String deployId,String formId,String nodeCode);


    /**
     * 根据部署编号、表单编号、节点编码查询节点表单字段限制
     * @param deployId
     * @param formId
     * @param flowCode
     * @return
     */
    List<FormFieldLimitDomain> getFormFieldLimitByFlowCode(String deployId,String formId,String flowCode);

    /**
     * 提交流程时检查强制选人功能是否有遗漏点
     * @param taskId
     * @return
     */
    ResponseResult checkForcePickByForm(String taskId);
}
